#include "CentralTabBar.h"

#include <QApplication>
#include <QDebug>
#include <QMouseEvent>
#include <QPainter>
#include <QStyleOption>
#include <QStylePainter>

CentralTabBar::CentralTabBar(QWidget *parent) : CTabBar(parent) {
    m_readyDrag = false;
    m_dragOffset = QMargins(0, 40, 0, 40);
    lastLeftBtn = lastRightBtn = nullptr;
}

void CentralTabBar::mousePressEvent(QMouseEvent *event) {
    QTabBar::mousePressEvent(event);

    int index = tabAt(event->pos());
    if (index < 0) {
        return;
    }

    QRect rect = tabRect(index);
    QPoint cur = event->pos() - rect.topLeft();

    lastPressPos = cur;
    lastTabRect = rect;

    lastLeftBtn = tabButton(index, QTabBar::LeftSide);
    lastRightBtn = tabButton(index, QTabBar::RightSide);

    lastLeftBtnPos = lastLeftBtn ? lastLeftBtn->pos() : QPoint();
    lastRightBtnPos = lastRightBtn ? lastRightBtn->pos() : QPoint();

    m_readyDrag = true;
}

void CentralTabBar::mouseMoveEvent(QMouseEvent *event) {
    QTabBar::mouseMoveEvent(event);

    if (m_readyDrag) {
        QRect rect = this->rect();
        rect.adjust(-m_dragOffset.left(), -m_dragOffset.top(), m_dragOffset.right(),
                    m_dragOffset.bottom());
        if ((event->buttons() & Qt::LeftButton) && (count() == 1 || !rect.contains(event->pos()))) {
            int index = this->currentIndex();
            if (index < 0) {
                return;
            }
            // Release Mouse
            QMouseEvent e(QEvent::MouseButtonRelease, event->pos(), Qt::LeftButton, Qt::NoButton,
                          Qt::NoModifier);
            QApplication::sendEvent(this, &e);
            emit dragStarted(index, lastPressPos, lastTabShot());
        }
    }
}

void CentralTabBar::mouseReleaseEvent(QMouseEvent *event) {
    QTabBar::mouseReleaseEvent(event);
    m_readyDrag = false;
}

void CentralTabBar::leaveEvent(QEvent *event) {
    QTabBar::leaveEvent(event);
    m_readyDrag = false;
}

QPixmap CentralTabBar::lastTabShot() const {
    int index = currentIndex();
    if (index < 0) {
        return QPixmap();
    }

    QStyleOptionTabV4 tab;
    initStyleOption(&tab, index);

    QRect rect = tabRect(index);
    QPoint offset = -rect.topLeft();

    QPixmap pixmap(rect.size());
    pixmap.fill(Qt::transparent);

    QPainter p(&pixmap);
    p.translate(-rect.topLeft());
    style()->drawControl(QStyle::CE_TabBarTab, &tab, &p, this);

    QStyleOptionTab option;
    initStyleOption(&option, 0);

    p.translate(-offset);

    offset = -lastTabRect.topLeft();
    if (lastLeftBtn) {
        QPixmap bmp(lastLeftBtn->size());
        bmp.fill(Qt::transparent);
        lastLeftBtn->render(&bmp);
        p.drawPixmap(QRect(lastLeftBtnPos + offset, lastLeftBtn->size()), bmp);
    }
    if (lastRightBtn) {
        QPixmap bmp(lastRightBtn->size());
        bmp.fill(Qt::transparent);
        lastRightBtn->render(&bmp);
        p.drawPixmap(QRect(lastRightBtnPos + offset, lastRightBtn->size()), bmp);
    }

    return pixmap;
}

QMargins CentralTabBar::dragOffset() const {
    return m_dragOffset;
}

void CentralTabBar::setDragOffset(const QMargins &dragOffset) {
    m_dragOffset = dragOffset;
}
